home *** CD-ROM | disk | FTP | other *** search
-
- static char rcsid[] =
- "$Id: gexample.c,v 1.3 1997/07/09 13:24:42 pvmsrc Exp $";
-
- /*
- * PVM version 3.4: Parallel Virtual Machine System
- * University of Tennessee, Knoxville TN.
- * Oak Ridge National Laboratory, Oak Ridge TN.
- * Emory University, Atlanta GA.
- * Authors: J. J. Dongarra, G. E. Fagg, M. Fischer
- * G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
- * P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
- * (C) 1997 All Rights Reserved
- *
- * NOTICE
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted
- * provided that the above copyright notice appear in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * Neither the Institutions (Emory University, Oak Ridge National
- * Laboratory, and University of Tennessee) nor the Authors make any
- * representations about the suitability of this software for any
- * purpose. This software is provided ``as is'' without express or
- * implied warranty.
- *
- * PVM version 3 was funded in part by the U.S. Department of Energy,
- * the National Science Foundation and the State of Tennessee.
- */
-
- /* Example of some group function and reduction functions in PVM
- *
- * 11 March 1994 - Creation by P. Papadopoulos (phil@msr.epm.ornl.gov)
- * 27 June 1997 - updated to allow spmd-style startups for PVM 3.4
- *
- *
- */
- #include <stdio.h>
- #ifdef HASSTDLIB
- #include <stdlib.h>
- #endif
-
- #include "pvm3.h"
-
- #define min(u,v) ( (u) < (v) ? (u) : (v) )
- #define max(u,v) ( (u) > (v) ? (u) : (v) )
-
- #define MATRIXGROUP "matrix"
- #define DEFAULT_DIMENSION 100
- #define DEFAULT_NPROC 10
- #define INITTAG 1000
- #define SUMTAG INITTAG + 1
- #define PRODTAG SUMTAG + 1
- extern void calcprod();
- main()
- {
- int info, mytid, myinst, gsize, nproc = 0;
- int maxmax;
- int dimension = 0;
- int ninst, error;
- int tids[32]; int *subblock, *colsum;
- double *colprod;
- int blksize,nextra,mysrow,i,j,sumsqr,itemp;
-
- int *stids;
- int spmd = 0; /* flag to indicate we were started in a spmd-style */
- int nsibs;
-
-
- mytid = pvm_mytid(); /* enroll */
-
- if ((nsibs = pvm_siblings( &stids )) > 1) /* nsibs spawned together */
- spmd = 1;
-
- if( (myinst = pvm_joingroup(MATRIXGROUP)) < 0 )
- {
- pvm_perror( "Could not join group \n" );
- pvm_exit();
- exit( -1 );
- }
-
- if ( myinst == 0 )
- {
- printf(" This program demonstrates some group and reduction \n");
- printf(" operations in PVM. The output displays the \n");
- printf(" the product of the first column of a Toeplitz matrix\n");
- printf(" and the matrix 1-norm. The matrix data is distributed \n");
- printf(" among several processors. The Toeplitz matrix is \n");
- printf(" symmetric with the first row being the row \n");
- printf(" vector [1 2 ... n].\n");
- if ( !spmd && pvm_parent() == PvmNoParent )
- {
- while ( nproc <= 0 || nproc > 32 || dimension <= 0)
- {
- printf( " Input dimension ( >0 ) of matrix: " );
- scanf( "%d", &dimension );
- printf( " Input number of tasks (1-32): " );
- scanf( "%d", &nproc );
- }
- }
- else
- {
- nproc = DEFAULT_NPROC;
- dimension = DEFAULT_DIMENSION;
- }
-
- if (!spmd && nproc > 1)
- {
- ninst = pvm_spawn( "gexample", (char **) 0, 0, "",
- nproc-1, tids);
- nproc = min (nproc, ninst + 1);
- }
-
- if (spmd)
- nproc = nsibs;
-
- pvm_initsend( PvmDataDefault );
- pvm_pkint( &nproc, 1, 1 );
- pvm_pkint( &dimension, 1, 1 );
- if (spmd)
- pvm_mcast(stids, nsibs, INITTAG);
- else
- pvm_mcast( tids, nproc - 1, INITTAG );
-
- printf("\n --> Using %d processors <-- \n\n", nproc);
- }
-
- else /* other nodes receive the number of processors from 0 */
- {
- pvm_recv( -1, INITTAG );
- pvm_upkint( &nproc, 1, 1 );
- pvm_upkint( &dimension, 1, 1);
- }
-
- /* Make the group static. freezegroup will wait until nproc tids have
- joined the group. */
-
- info = pvm_freezegroup(MATRIXGROUP,nproc);
-
- /* Map matrix rows to processors -- */
-
- blksize = dimension/nproc ;
- nextra = dimension % nproc;
-
- if( myinst < nextra )
- {
- mysrow = (blksize + 1) * myinst;
- blksize++;
- }
- else
- mysrow = (blksize + 1)*(nextra) + blksize*(myinst - nextra);
-
- subblock = (int *) calloc(blksize*dimension,sizeof(int));
- colsum = (int *) calloc(dimension,sizeof(int));
- colprod = (double *) calloc(dimension,sizeof(double));
-
- if (mysrow >= dimension) /* too many processors ! */
- blksize = 0;
-
- /* Assign data to this subblock. The entries below make the entire matrix
- a symmetric Toeplitz matrix (i.e. diagonals are of constant value) */
-
- for (i = 0; i < blksize; i++)
- for (j = 0; j < dimension; j++)
- *(subblock + i*dimension + j) = 1 + abs(mysrow + i - j);
-
- /* Locally compute the sum of each column and put into colsum */
- for (j = 0; j < dimension; j++)
- {
- colsum[j] = 0;
- colprod[j] = 1.0;
- }
-
- for (i = 0; i < blksize; i ++)
- for(j = 0; j < dimension; j++)
- {
- itemp = *(subblock + j + i*dimension);
- colsum[j] += abs( itemp );
- colprod[j] *= abs( itemp );
- }
-
- /* synchronize the computation and then reduce using pvm_sum. This gives
- a row vector that has the all the columns sums */
-
- if ( pvm_reduce(PvmSum,colsum,dimension,PVM_INT,SUMTAG,
- MATRIXGROUP,0) < 0 )
- pvm_perror( "pvm_reduce had an error \n") ;
-
- pvm_reduce(calcprod,colprod,dimension,PVM_DOUBLE,PRODTAG,
- MATRIXGROUP,0);
-
- if( myinst == 0)
- {
- maxmax = 0;
- for (j = 0; j < dimension; j++)
- maxmax = max(colsum[j],maxmax);
-
- printf(" The 1-Norm is %d \n" , maxmax );
- printf(" ( Should be the sum of the integers from 1 to %d )\n",
- dimension );
- printf(" The product of column 1 is %g \n" , colprod[0] );
- printf(" ( Should be %d factorial)\n", dimension);
- }
-
- info = pvm_barrier(MATRIXGROUP,-1); /* make sure processes are finished*/
- if (info < 0)
- printf("Barrier failed with result code %d\n", info);
-
- pvm_lvgroup(MATRIXGROUP);
-
- free(subblock); free(colsum); free(colprod);
- pvm_exit();
- }
-
-
- /*** A User-defined Reduction Function ***/
- void
- calcprod(datatype,x,y,num,info)
- int *datatype;
- double *x,*y;
- int *num, *info;
- {
- int i;
- for (i = 0 ; i < *num; i++)
- x[i] *= y[i];
- }
-